package okhttp.itydl.com.download.file;

import android.content.Context;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp.itydl.com.download.http.DownloadCallback;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 网络请求管理
 *
 * @author howard
 */
public class HttpManager {

    private static final HttpManager sHttpManager = new HttpManager();
    private OkHttpClient mOkHttpClient;
    private Context mContext;
    public static int NETWORK_ERROR_CODE = 0;
    public static int NETWORK_CALLBACK_ERROR = 1;
    public static int CONTENT_LENGTH_ERROR_CODE = 2;

    private HttpManager() {
        mOkHttpClient = new OkHttpClient();
    }

    public static HttpManager getInstance() {
        return sHttpManager;
    }

    public void init(Context context) {
        this.mContext = context;
    }

    /**
     * 同步请求
     *
     * @param url
     * @return
     */
    public Response syncRequest(String url) {
        Request request = new Request.Builder().url(url).build();
        try {
            return mOkHttpClient.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 同步请求,设置Range
     *
     * @param url
     * @return
     */
    public Response syncRangeRequest(String url, long start, long end) {
        // 设置本次http请求所请求的数据的区间。该线程请求的不应该是整个服务器文件的数据，
        // 而是[该线程所分配的那段区间的数据]。
        // 因此，我要给该线程获取数据的时候分配一个区间范围，表示我只关心这一段。
        // 使用setRequestProperty设置一个Range范围，它的标准写法如下：
        // 已经下载的新的起始位置为上次下载进度处（如果实现续传的话）
        Request request = new Request.Builder().
                url(url).
                addHeader("Range", "bytes=" + start + "-" + end).
                build();
        try {
            return mOkHttpClient.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 异步请求，回调传给调用方（调用方自己定义实现Callback类，自己处理回调结果）
     *
     * @param url
     * @param callback
     */
    public void asyncRequest(String url, Callback callback) {
        Request request = new Request.Builder().url(url).build();
        // 自己不实现，交给调用方自己去实现
        mOkHttpClient.newCall(request).enqueue(callback);
    }

    /**
     * 异步请求
     *
     * @param url
     * @param callback
     */
    public void asyncRequest(final String url, final DownloadCallback callback) {

        Request request = new Request.Builder().url(url).build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful() && callback != null) {
                    callback.fail(NETWORK_ERROR_CODE, "请求失败");
                }
                // 下载路径File
                File file = FileStorageManager.getInstance().getFileByName(url);

                // 开始下载到File里面
                byte[] buffer = new byte[1024 * 500];
                int len;
                FileOutputStream fileOut = new FileOutputStream(file);
                InputStream inStream = response.body().byteStream();
                while ((len = inStream.read(buffer, 0, buffer.length)) != -1) {
                    fileOut.write(buffer, 0, len);
                    fileOut.flush();
                }
                callback.success(file);
                inStream.close();
            }
        });
    }

}
